<template>
    <!-- #ifdef APP-NVUE -->
    <cell :keep-scroll-position="keepScrollPosition">
        <!-- #endif -->
        <view
            :class="{ 'uv-list-item--disabled': disabled }"
            :style="[
                $uv.addStyle(customStyle),
                {
                    'background-color': customStyle.backgroundColor
                        ? customStyle.backgroundColor
                        : '#fff',
                },
            ]"
            :hover-class="
                (!clickable && !link) || disabled || showSwitch
                    ? ''
                    : 'uv-list-item--hover'
            "
            class="uv-list-item"
            @click="onClick"
        >
            <view
                v-if="!isFirstChild"
                class="border--left"
                :class="{ 'uv-list--border': border }"
            ></view>
            <view class="uv-list-item__wrapper">
                <slot>
                    <view
                        class="uv-list-item__container"
                        :class="{
                            'container--right': showArrow || link,
                            'flex--direction': directionData === 'column',
                        }"
                        :style="{
                            paddingTop: padding.top,
                            paddingLeft: padding.left,
                            paddingRight: padding.right,
                            paddingBottom: padding.bottom,
                        }"
                    >
                        <slot name="header">
                            <view class="uv-list-item__header">
                                <view v-if="thumb" class="uv-list-item__icon">
                                    <image
                                        :src="thumb"
                                        class="uv-list-item__icon-img"
                                        :class="['uv-list--' + thumbSize]"
                                    />
                                </view>
                                <view
                                    v-else-if="showExtraIcon"
                                    class="uv-list-item__icon"
                                >
                                    <uv-icon
                                        :name="extraIcon.icon"
                                        :customPrefix="extraIcon.customPrefix"
                                        :color="extraIcon.color"
                                        :size="extraIcon.size"
                                    />
                                </view>
                            </view>
                        </slot>
                        <slot name="body">
                            <view
                                class="uv-list-item__content"
                                :class="{
                                    'uv-list-item__content--center':
                                        thumb ||
                                        showExtraIcon ||
                                        showBadge ||
                                        showSwitch,
                                }"
                            >
                                <text
                                    v-if="title"
                                    class="uv-list-item__content-title"
                                    :class="[ellipsis && `uv-line-${ellipsis}`]"
                                >
                                    {{ title }}
                                </text>
                                <text
                                    v-if="note"
                                    class="uv-list-item__content-note"
                                >
                                    {{ note }}
                                </text>
                            </view>
                        </slot>
                        <slot name="footer">
                            <view
                                v-if="rightText || showBadge || showSwitch"
                                class="uv-list-item__extra"
                                :class="{
                                    'flex--justify': directionData === 'column',
                                }"
                            >
                                <text
                                    v-if="rightText"
                                    class="uv-list-item__extra-text"
                                >
                                    {{ rightText }}
                                </text>
                                <uv-badge
                                    v-if="showBadge"
                                    :show="
                                        !!(
                                            badge.show ||
                                            badge.isDot ||
                                            badge.value
                                        )
                                    "
                                    :isDot="badge.isDot"
                                    :value="badge.value"
                                    :max="badge.max"
                                    :type="badge.type"
                                    :showZero="badge.showZero"
                                    :bgColor="badge.bgColor"
                                    :color="badge.color"
                                    :shape="badge.shape"
                                    :numberType="badge.numberType"
                                    :inverted="badge.inverted"
                                    customStyle="margin-left: 4px;"
                                ></uv-badge>
                                <uv-switch
                                    v-if="showSwitch"
                                    :value="switchChecked"
                                    :disabled="disabled"
                                    @change="onSwitchChange"
                                ></uv-switch>
                            </view>
                        </slot>
                    </view>
                </slot>
            </view>
            <uv-icon
                v-if="showArrow || link"
                size="34rpx"
                class="uv-icon-wrapper"
                color="#bbb"
                name="arrow-right"
            />
        </view>
        <!-- #ifdef APP-NVUE -->
    </cell>
    <!-- #endif -->
</template>

<script>
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
/**
 * ListItem 列表子组件
 * @description 列表子组件
 * @tutorial https://ext.dcloud.net.cn/plugin?id=24
 * @property {String} 	title 							标题
 * @property {String} 	note 							描述
 * @property {String} 	thumb 							左侧缩略图，若thumb有值，则不会显示扩展图标
 * @property {String}  	thumbSize = [lg|base|sm]		略缩图大小
 * 	@value 	 lg			大图
 * 	@value 	 base		一般
 * 	@value 	 sm			小图
 * @property {String} 	rightText 						右侧文字内容
 * @property {Boolean} 	disabled = [true|false]			是否禁用
 * @property {Boolean} 	clickable = [true|false] 		是否开启点击反馈
 * @property {String} 	link = [navigateTo|redirectTo|reLaunch|switchTab] 是否展示右侧箭头并开启点击反馈
 *  @value 	navigateTo 	同 uni.navigateTo()
 * 	@value redirectTo 	同 uni.redirectTo()
 * 	@value reLaunch   	同 uni.reLaunch()
 * 	@value switchTab  	同 uni.switchTab()
 * @property {String | PageURIString} 	to  			跳转目标页面
 * @property {Boolean} 	showBadge = [true|false] 		是否显示数字角标
 * @property {Object} 	badge  扩展数字角标的参数，格式为 :badge="{value: 122}"
 * @property {Boolean} 	showSwitch = [true|false] 		是否显示Switch
 * @property {Boolean} 	switchChecked = [true|false] 	Switch是否被选中
 * @property {Boolean} 	showExtraIcon = [true|false] 	左侧是否显示扩展图标
 * @property {Object} 	extraIcon 						扩展图标参数，格式为 :extraIcon="{icon: 'photo',size: '30px'}"
 * @property {String} 	direction = [row|column]		排版方向
 * @value row 			水平排列
 * @value column 		垂直排列
 * @event {Function} 	click 							点击 uniListItem 触发事件
 * @event {Function} 	switchChange 					点击切换 Switch 时触发
 */
export default {
    name: 'uv-list-item',
    mixins: [mpMixin, mixin],
    emits: ['click', 'switchChange'],
    props: {
        direction: {
            type: String,
            default: 'row',
        },
        title: {
            type: String,
            default: '',
        },
        note: {
            type: String,
            default: '',
        },
        ellipsis: {
            type: [Number, String],
            default: 0,
        },
        disabled: {
            type: [Boolean, String],
            default: false,
        },
        clickable: {
            type: Boolean,
            default: false,
        },
        showArrow: {
            type: [Boolean, String],
            default: false,
        },
        link: {
            type: [Boolean, String],
            default: false,
        },
        to: {
            type: String,
            default: '',
        },
        showSwitch: {
            type: [Boolean, String],
            default: false,
        },
        switchChecked: {
            type: [Boolean, String],
            default: false,
        },
        showBadge: {
            type: [Boolean, String],
            default: false,
        },
        badge: {
            type: Object,
            default() {
                return {}
            },
        },
        rightText: {
            type: String,
            default: '',
        },
        thumb: {
            type: String,
            default: '',
        },
        thumbSize: {
            type: String,
            default: 'base',
        },
        showExtraIcon: {
            type: [Boolean, String],
            default: false,
        },
        extraIcon: {
            type: Object,
            default() {
                return {
                    name: '',
                    color: '#000000',
                    size: 20,
                    customPrefix: '',
                }
            },
        },
        border: {
            type: Boolean,
            default: false,
        },
        customStyle: {
            type: Object,
            default() {
                return {
                    padding: '',
                    backgroundColor: '#FFFFFF',
                }
            },
        },
        keepScrollPosition: {
            type: Boolean,
            default: false,
        },
    },
    computed: {
        directionData() {
            return this.direction
                ? this.direction
                : this.parentData.direction
                  ? this.parentData.direction
                  : 'row'
        },
    },
    watch: {
        'customStyle.padding': {
            handler(padding) {
                if (padding) this.setPadding(padding)
            },
            immediate: true,
        },
    },
    data() {
        return {
            isFirstChild: false,
            padding: {
                top: '',
                right: '',
                bottom: '',
                left: '',
            },
            parentData: {
                direction: 'row',
                padding: 0,
            },
        }
    },
    created() {
        this.updateParentData()
    },
    mounted() {
        this.init()
        this.list = this.getForm()
        // 判断是否存在 uv-list 组件
        if (this.list) {
            if (!this.list.firstChildAppend) {
                this.list.firstChildAppend = true
                this.isFirstChild = true
            }
        }
    },
    methods: {
        init() {
            if (!this.parent) {
                this.$uv.error('uv-list-item必须搭配uv-list组件使用')
            }
            this.$nextTick(() => {
                if (
                    !(
                        this.padding.top ||
                        this.padding.right ||
                        this.padding.bottom ||
                        this.padding.left
                    )
                ) {
                    this.setPadding(this.parentData.padding)
                }
            })
        },
        updateParentData() {
            this.getParentData('uv-list')
        },
        setPadding(padding) {
            if (typeof padding == 'number') {
                padding += ''
            }
            let paddingArr = padding.split(' ')
            if (paddingArr.length === 1) {
                const allPadding = paddingArr[0]
                this.padding = {
                    top: allPadding,
                    right: allPadding,
                    bottom: allPadding,
                    left: allPadding,
                }
            } else if (paddingArr.length === 2) {
                const [verticalPadding, horizontalPadding] = paddingArr
                this.padding = {
                    top: verticalPadding,
                    right: horizontalPadding,
                    bottom: verticalPadding,
                    left: horizontalPadding,
                }
            } else if (paddingArr.length === 4) {
                const [topPadding, rightPadding, bottomPadding, leftPadding] =
                    paddingArr
                this.padding = {
                    top: topPadding,
                    right: rightPadding,
                    bottom: bottomPadding,
                    left: leftPadding,
                }
            }
        },
        /**
         * 获取父元素实例
         */
        getForm(name = 'uniList') {
            let parent = this.$parent
            let parentName = parent.$options.name
            while (parentName !== name) {
                parent = parent.$parent
                if (!parent) return false
                parentName = parent.$options.name
            }
            return parent
        },
        onClick() {
            if (this.to !== '') {
                this.openPage()
                return
            }
            if (this.clickable || this.link) {
                this.$emit('click', {
                    data: {},
                })
            }
        },
        onSwitchChange(e) {
            this.$emit('switchChange', e)
        },
        openPage() {
            if (
                ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].indexOf(
                    this.link,
                ) !== -1
            ) {
                this.pageApi(this.link)
            } else {
                this.pageApi('navigateTo')
            }
        },
        pageApi(api) {
            let callback = {
                url: this.to,
                success: (res) => {
                    this.$emit('click', {
                        data: res,
                    })
                },
                fail: (err) => {
                    this.$emit('click', {
                        data: err,
                    })
                },
            }
            switch (api) {
                case 'navigateTo':
                    uni.navigateTo(callback)
                    break
                case 'redirectTo':
                    uni.redirectTo(callback)
                    break
                case 'reLaunch':
                    uni.reLaunch(callback)
                    break
                case 'switchTab':
                    uni.switchTab(callback)
                    break
                default:
                    uni.navigateTo(callback)
            }
        },
    },
}
</script>

<style lang="scss" scoped>
$show-lines: 1;
@import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
$uv-font-size-sm: 12px;
$uv-font-size-base: 28rpx;
$uv-font-size-lg: 16px;
$uv-spacing-col-lg: 12px;
$uv-spacing-row-lg: 15px;
$uv-img-size-sm: 20px;
$uv-img-size-base: 26px;
$uv-img-size-lg: 40px;
$uv-border-color: #e5e5e5;
$uv-bg-color-hover: #f1f1f1;
$uv-text-color-grey: #999;
$list-item-pd: $uv-spacing-col-lg $uv-spacing-row-lg;

.uv-list-item {
    @include flex(row);
    font-size: $uv-font-size-lg;
    position: relative;
    justify-content: space-between;
    align-items: center;
    background-color: #fff;
    /* #ifdef H5 */
    cursor: pointer;
    /* #endif */
}

.uv-list-item--disabled {
    opacity: 0.3;
}

.uv-list-item--hover {
    background-color: $uv-bg-color-hover !important;
}

.uv-list-item__wrapper {
    @include flex(column);
    flex: 1;
}

.uv-list-item__container {
    position: relative;
    @include flex(row);
    padding: $list-item-pd;
    padding-left: $uv-spacing-row-lg;
    flex: 1;
    overflow: hidden;
}

.container--right {
    padding-right: 0;
}

.uv-list--border {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    /* #ifdef APP-NVUE */
    border-top-color: $uv-border-color;
    border-top-style: solid;
    border-top-width: 0.5px;
    /* #endif */
}

/* #ifndef APP-NVUE */
.uv-list--border:after {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    height: 1px;
    content: '';
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
    background-color: $uv-border-color;
}

/* #endif */
.uv-list-item__content {
    @include flex(column);
    padding-right: 8px;
    flex: 1;
    color: #3b4144;
    justify-content: space-between;
    overflow: hidden;
}

.uv-list-item__content--center {
    justify-content: center;
}

.uv-list-item__content-title {
    font-size: $uv-font-size-base;
    color: #3b4144;
    overflow: hidden;
}

.uv-list-item__content-note {
    margin-top: 6rpx;
    color: $uv-text-color-grey;
    font-size: $uv-font-size-sm;
    overflow: hidden;
}

.uv-list-item__extra {
    @include flex(row);
    justify-content: flex-end;
    align-items: center;
}

.uv-list-item__header {
    @include flex(row);
    align-items: center;
}

.uv-list-item__icon {
    margin-right: 18rpx;
    flex-direction: row;
    justify-content: center;
    align-items: center;
}

.uv-list-item__icon-img {
    /* #ifndef APP-NVUE */
    display: block;
    /* #endif */
    height: $uv-img-size-base;
    width: $uv-img-size-base;
    margin-right: 10px;
}

.uv-icon-wrapper {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    align-items: center;
    padding: 0 10px;
}

.flex--direction {
    flex-direction: column;
    /* #ifndef APP-NVUE */
    align-items: initial;
    /* #endif */
}

.flex--justify {
    /* #ifndef APP-NVUE */
    justify-content: initial;
    /* #endif */
}

.uv-list--lg {
    height: $uv-img-size-lg;
    width: $uv-img-size-lg;
}

.uv-list--base {
    height: $uv-img-size-base;
    width: $uv-img-size-base;
}

.uv-list--sm {
    height: $uv-img-size-sm;
    width: $uv-img-size-sm;
}

.uv-list-item__extra-text {
    color: $uv-text-color-grey;
    font-size: $uv-font-size-sm;
}
</style>
